package cz.pecinovsky.česky.oopnz._125_;
//Příliš žluťoučký kůň úpěl ďábelské ódy


////////////////////////////////////////////////////////////////////////////////
//%%+  +++++ Konec ignorovaného počátečního textu +++++
//%A+ >=133z

import cz.pecinovsky.česky.oopnz.utility.IO;
//%A-
//%X+ xxxxx Začátek přeskakovaného textu xxxxx
/*******************************************************************************
 *<pre>
 * Předchozí:   Není - toto_je_nově_definovaná_třída
 *              Ttt v projektu Ppp
 * Následující: Prozatím není
 *
 * Projekt  Ppp
 *   + Přidáno
 *   - Odebráno
 *   ~ Změněno
 *</pre>
 */
public class KTI_130_
{    private KTI_130_() {}   static
////////////////////////////////////////////////////////////////////////////////
//%X- ----- Konec přeskakovaného textu -----


/*******************************************************************************
 * Třída {@code KTI} a její instance slouží pro demonstrace a experimenty
 * při výkladu zavádění a inicializací tříd a konstrukci jejích instancí.
 *
 * @author Rudolf PECINOVSKÝ
 * @version 6.03.2017 — 2010-11-08
 */
public class KTI
{
    static  //Úvodní statický inicializační blok
    {/*## 1 ##*/
        IO.zpráva("Konstruktor třídy KTI\n\nSTART");
        tiskniStatickéAtributy("Konstrukce třídy KTI - START");
    }

    //Úvodní instanční inicializační blok
    {/*## 2 ##*/
        IO.zpráva("Inicializace instance KTI\n\nSTART");
        System.out.println("\n-------------------------------------" +
                           "\nSTART inicializace pro " + this);
    }


//== KONSTANTNÍ ATRIBUTY TŘÍDY =================================================

    static  //Před deklarací konstant
    {/*## 3 ##*/
        //Použití nedeklarované konstanty je syntaktická chyba,
        //i kdyby už měla přiřazenou hodnotu při překladu
//        System.out.println("PŘELOŽENÁ:    " + PŘELOŽENÁ );

        //Skryté použití ale projde - viz tisk v úvodním bloku
    }

    //Konstanta inicializovaná v době překladu - je-li hodnota konstanty
    //známa v době překladu, inicializuje ji už překladač
    private static final String PŘELOŽENÁ = "PŘELOŽENÁ";

    //Konstanta inicializovaná až při zavádění třídy
    public static final Class CLASS_OBJEKT = KTI.class;

    //Konstanta inicializovaná až při zavádění třídy
    public static final String SPOČTENÁ;

    static  //Po deklaraci konstant
    {/*## 4 ##*/
//        //Dosud neinicializovaná konstanta se také nesmí používat
//        System.out.println("SPOČTENÁ: " + SPOČTENÁ );

        SPOČTENÁ = CLASS_OBJEKT.getName();

        //Po inicializaci se konstanty již smí používat
        System.out.println("\nxxx Tisk po inicializaci třídních konstant:" +
                           "\n    - PŘELOŽENÁ:    " + PŘELOŽENÁ +
                           "\n    - CLASS_OBJEKT: " + CLASS_OBJEKT +
                           "\n    - SPOČTENÁ:     " + SPOČTENÁ);
    }

    //Atributem třídy může být i instance dané třídy. Je však třeba dbát na to,
    //aby byl tento atribut inicializován až po všech atributech třídy,
    //které jsou při jeho inicializaci používány.
    //Následující deklarace má problém s konstatním atributem ZAVEDENO
    //stejně jako s proměnným atributem počet.
    //Problémy se odstraní přemístěním jeho inicializace
    //za všechny atributy inicializace atributů třídy.
//    public static final KTI JÁ = new KTI();



//== PROMĚNNÉ ATRIBUTY TŘÍDY ===================================================

    static //Před deklarací proměnných
    {/*## 5 ##*/
//        //Nedeklarovaná proměnná se také nesmí používat
//        System.out.println("proměnná: " + proměnná );
    }

    private static String proměnná;
    private static int    počet = 0;

    static  //Po deklaraci proměnných
    {/*## 6 ##*/
        //Proměnná se smí používat i neinicializovaná
        System.out.println("\nxxx Tisk po deklaraci třídních proměnných:" +
                           "\n    - proměnná:    " + proměnná);
        proměnná = "PROMĚNNÁ";  //Proměnná je inicializována až teď
    }



//== STATICKÝ INICIALIZAČNÍ BLOK - STATICKÝ KONSTRUKTOR ========================
//== KONSTANTNÍ ATRIBUTY INSTANCÍ ==============================================

    private final int ID;
    //"Rodné číslo" instance je nutno nejprve spočítat
    {/*## 7 ##*/
        počet = počet + 1;  //Zvětším statický atribut
        ID    = počet;      //a zapamatuji si jeho aktuální hodnotu
        System.out.println("Atribut ID inicializován: " + this);
    }


//== PROMĚNNÉ ATRIBUTY INSTANCÍ ================================================

    //V inicializaci instančních atributů se smí používat pouze
    //dříve deklarované instanční atributy a již inicializované konstanty
    //Atributy třídy se však smí používat všechny, protože ty mají být
    //v době inicializace instance už dávno připraveny
    private String čas = ZAVEDENO;

    //V inicializaci instance je povoleno použití parametru this
    //V následující inicializaci se ptám instance na její class-objekt
    String název = "[" + this.getClass() + "]";    //Prozatímní název

    String zdroj;



//== PŘÍSTUPOVÉ METODY VLASTNOSTÍ TŘÍDY ========================================
//== OSTATNÍ NESOUKROMÉ METODY TŘÍDY ===========================================

    /***************************************************************************
     * Vytiskne na standardní výstup všechny statické atributy třídy
     *
     * @param nadpis Nadpis před jednotlivými tisky
     */
    public static void tiskniStatickéAtributy(String nadpis)
    {
        System.out.println("\n" + nadpis +
                           "\n  - PŘELOŽENÁ=" + PŘELOŽENÁ +
                              ",  CLASS_OBJEKT=" + CLASS_OBJEKT +
                              ",  proměnná=" + proměnná +
                              ",  počet=" + počet +
                           "\n    ZAVEDENO=" + ZAVEDENO
                         );
    }



//##############################################################################
//== KONSTRUKTORY A TOVÁRNÍ METODY =============================================

    /***************************************************************************
     * Bezparametrický konstruktor pro test inicializace.
     */
    public KTI()
    {
        System.out.println("Vstup do těla konstruktoru " + this);
        zdroj = "Bezparametrický";
        System.out.println("Konec těla konstruktoru " + this);
    }


    /***************************************************************************
     * Jednoparametrický konstruktor pro test delegace zodpovědnosti.
     *
     * @param název Název vytvářené instance
     */
    public KTI(String název)
    {
//        //Před předáním odpovědnosti nesmí nic být
//        System.out.println("1-parametrický pro " + this);
        this(název, připrav("1-param"));
        System.out.println("Konec 1-parametrický");
    }


    /***************************************************************************
     * Dvouparametrický konstruktor pro test delegace zodpovědnosti.
     *
     * @param název Název vytvářené instance
     * @param zdroj Charakteristika  žadatele
     */
    public KTI(String název, String zdroj)
    {
        this(název, připrav("2-param"), zdroj);
        String lok = "2-parametrický";
        System.out.println("Konec " + lok);
    }


    /***************************************************************************
     * Tříparametrický konstruktor pro test delegace zodpovědnosti.
     *
     * @param název Název vytvářené instance
     * @param zdroj Charakteristika  žadatele
     * @param prazdroj Druhá část hodnoty atributu {@code zdroj}
     */
    public KTI(String název, String zdroj, String prazdroj)
    {
        System.out.println("Vstup do těla 3-parametrického pro " + this +
        "\n   Název=" + název + ", Zdroj=" + zdroj + ", prazdroj=" + prazdroj);
        String nepoužitá;
        String podtržení;
        this.název     = název;
        String součet  = "«" + prazdroj + " -> " + zdroj + "»";
        this.zdroj     = součet;
        String lokální = "Konec 3-parametrický: ";
        podtržení = "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
        System.out.println(lokální + this + podtržení);
    }



//== ABSTRAKTNÍ METODY =========================================================
//== PŘÍSTUPOVÉ METODY VLASTNOSTÍ INSTANCÍ =====================================
//== OSTATNÍ NESOUKROMÉ METODY INSTANCÍ ========================================

    /** Vrátí popis instance. */
    @Override
    public String toString()
    {
        return "KTI_" + ID + "(název=" + název + ", zdroj=" + zdroj +
               ", ##čas=" + čas + ")";
    }



//== SOUKROMÉ A POMOCNÉ METODY TŘÍDY ===========================================

    /***************************************************************************
     * Pomocná statická metoda sloužící k zaznamenání okamžiku,
     * kdy se vyhodnocují parametry.
     *
     * @param nadpis Nadpis před jednotlivými tisky
     */
    private static String připrav(String text)
    {
        System.out.println("  === Přípravuji: " + text);
        return text;
    }



//== SOUKROMÉ A POMOCNÉ METODY INSTANCÍ ========================================
//== INTERNÍ DATOVÉ TYPY =======================================================
//== TESTY A METODA MAIN =======================================================
//
//    /***************************************************************************
//     * Testovací metoda.
//     */
//    public static void test()
//    {
//        KTI inst = new KTI();
//    }
//    /** @param args Parametry příkazového řádku - nepoužívané. */
//    public static void main( String[] args )  {  test();  }

    {/*## 8 ##*/
        System.out.println("STOP inicializace instance " + this +
                         "\n----------------------------");
        IO.zpráva("Konec inicializační části instance");
    }

    //Statický atribut deklarovaný až na konci těla
    private static final String ZAVEDENO = "" + new java.util.Date();
    static
    {/*## 9 ##*/
        tiskniStatickéAtributy("\nKonstrukce třídy KTI - STOP");
        System.out.println("=============================\n");
        IO.zpráva("Zavírá se konstruktor třídy KTI");
    }
}

//%%-  ----- Začátek ignorovaného závěrečného textu -----
////////////////////////////////////////////////////////////////////////////////
//== TESTY A METODA MAIN =======================================================

    /***************************************************************************
     * Testovací metoda.
     */
    public static void test()
    {
        new KTI("pokus");
        System.exit(0);
    }
    /** @param args Parametry příkazového řádku - nepoužívané. */
    public static void main( String[] args )  {  test();  }
}
